/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package snmpapplication.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import snmpapplication.Main;
import snmpapplication.beans.Ip;
import snmpapplication.beans.ManagedDevice;
import snmpapplication.log.Severity;

/**
 * Class used for retrieving & modification of the list of managed devices
 * @author APetcu
 */
public class DevicesManager {

    // contains the list of all devices
    public static ArrayList<ManagedDevice> deviceList;
    // path to the file that contains the managed devices list
    private static String path = "C://".concat("devices.txt");

    /**
     * Method used to load the device list from the file
     * @throws Exception 
     */
    public static synchronized void loadDevices() throws Exception {

        // initialize the list
        deviceList = new ArrayList<ManagedDevice>();

        try {
            // load from file
            BufferedReader br = new BufferedReader(new FileReader(new File(path)));

            // reading each line of the file
            String read = br.readLine();

            while (read != null) {

                // add to the list a coresponding ManagedDevice object
                deviceList.add(new ManagedDevice(new Ip(read.trim())));

                // read the next line in file
                read = br.readLine();
            }

            // close the file stream
            br.close();

        } catch (IOException ex) {
            // Exception in case the file is not found
            // create a new file to the default path
            File f = new File(path);
            f.createNewFile();

            // add a localhost(127.0.0.1) device to the list
            addDevice(new ManagedDevice(new Ip()));

            Main.log.log(new Severity(Severity.SEV_MED), "Device filelist not found, created new file at:" + path);
        }
    }

    /**
     * Method used to add a managed device to the list
     * @param md
     * @return 
     */
    public static boolean addDevice(ManagedDevice md) {
        try {
            // if the IP address of the new device is not in the list then add it
            if (isUnique(md.getIpAddress())) {
                PrintWriter bw = new PrintWriter(new FileWriter(new File(path), true));

                // add the new device 
                bw.println(md.getIpAddress().toString());
                bw.flush();
                bw.close();
                try {
                    // also add the device to the logical list
                    //deviceList.add(md);
                    synchronized (deviceList) {
                        loadDevices();
                    }
                } catch (Exception ex) {
                    Logger.getLogger(DevicesManager.class.getName()).log(Level.SEVERE, null, ex);
                }

                return true;

            } else {
                Main.log.log(new Severity(Severity.SEV_MIN), "IP" + md.getIpAddress().toString() + " not unique");
                // if the IP address already exists 
                return false;
            }

        } catch (IOException ex) {
            Main.log.log(new Severity(Severity.SEV_ERR), "IOException when adding new device: " + ex.getMessage());

            return false;
        }

    }

    /**
     * Method used to check the managed devices list for duplicates
     * @param ip
     * @return 
     */
    private static boolean isUnique(Ip ip) {
        try {

            for (ManagedDevice i : deviceList) {
                if (i.getIpAddress().toString().equals(ip.toString())) {
                    return false;
                }
            }
        } catch (Exception ex) {
            Main.log.log(new Severity(Severity.SEV_ERR), "IOException when adding new device: " + ex.getMessage());
        }

        return true;
    }

    /**
     * Method used to delete a device from the logical list and from the 
     * persistent list
     * @param md 
     */
    public static void deleteDevice(ManagedDevice md) {

        try {

            File inFile = new File(path);

            if (!inFile.isFile()) {
                //System.out.println("Parameter is not an existing file");
                Main.log.log(new Severity(Severity.SEV_ERR), "Input file not found!");
                return;
            }

            // Construct the new file that will later be renamed to the original filename.
            File tempFile = new File(inFile.getAbsolutePath() + ".tmp");

            // Open stream to both files
            BufferedReader br = new BufferedReader(new FileReader(path));
            PrintWriter pw = new PrintWriter(new FileWriter(tempFile));

            String line = null;

            // Read from the original file and write to the new
            // unless content matches data to be removed.
            while ((line = br.readLine()) != null) {

                if (!line.trim().equals(md.getIpAddress().toString())) {

                    pw.println(line);
                    pw.flush();
                }
            }
            pw.close();
            br.close();

            //Delete the original file
            if (!inFile.delete()) {
                //System.out.println("Could not delete file");
                Main.log.log(new Severity(Severity.SEV_ERR), "Could not delete temporary file");
                return;
            }

            //Rename the new file to the filename the original file had.
            if (!tempFile.renameTo(inFile)) {
                //System.out.println("Could not rename file");
                Main.log.log(new Severity(Severity.SEV_ERR), "Could not rename file");
            }

        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }
}
